<template>
	<div class="container" :style="{ ...container }">
		<div
			class="title-container"
			v-if="props.config.style.titleShow"
			:style="{ justifyContent: props.config.style.align }"
		>
			<div class="flex items-center">
				<i
					:class="['iconfont', props.config.style.titleIcon]"
					:style="{ ...titleIconStyle }"
					v-if="props.config.style.titleIconShow"
				></i>
				<span class="font-7" :style="{ ...titleStyle }">{{ props.config.style.title }}</span>
			</div>
			<div class="flex items-center" v-if="props.config.style.titleEndShow">
				<span class="font-7" :style="{ ...titleEndStyle }">{{ props.config.style.titleEnd }}</span>
				<i
					:class="['iconfont', props.config.style.titleEndIcon]"
					:style="{ ...titleEndIconStyle }"
					v-if="props.config.style.titleEndIconShow"
				></i>
			</div>
		</div>
		<div ref="chartContainer" class="chart-container"></div>
	</div>
</template>

<script setup>
	import config from './config'
	import { ref, onMounted, onBeforeUnmount, nextTick, computed, watch, reactive } from 'vue'
	import { Column } from '@antv/g2plot'
	import { cloneDeep, merge } from 'lodash-es'
	import datasetApi from '@/views/plugin/dashboard/api/datasetApi'
	import { designStore } from '@/views/plugin/dashboard/store'

	const useDesignStore = designStore()
	const props = defineProps({
		config: {
			type: Object,
			default: () => config
		}
	})

	// 接数据源
	const dataSet = reactive(cloneDeep(props.config.data))
	// 数据源 --- 调接口
	const dataSource = ref([])
	watch(
		() => props.config.dataSetConfig.dataSetJson,
		(newVal, oldVal) => {
			const dataSetJson = props.config.dataSetConfig.dataSetJson
			const isNull = dataSetJson && !!Object.keys(dataSetJson).length
			if (props.config.dataSetConfig.dataSetType === 1 && isNull && newVal !== oldVal) {
				// 模拟接口返回下拉数据
				datasetApi.preview(newVal).then((res) => {
					dataSource.value = res || []
					dataSet.chartData.value = dataSource.value
				})
			}
		},
		{ deep: true, immediate: true }
	)

	// 组件绑定数据 静态 / 数据源
	const formState = computed(() => {
		if (props.config.dataSetConfig.dataSetType === 1) {
			dataSet.xField.value = props.config.data.xField.field
			dataSet.yField.value = props.config.data.yField.field
			dataSet.seriesField.value = props.config.data.seriesField.field
			dataSet.chartData.value = dataSource.value
			return dataSet
		} else {
			return props.config.data
		}
	})

	const chartContainer = ref(null)
	const chartInstance = ref(null)
	const resizeObserver = ref(null)

	// 图表配置
	const chartOptions = computed(() => {
		const baseOptions = {
			data: formState.value.chartData.value || [],
			xField: formState.value.xField.value,
			yField: formState.value.yField.value,
			seriesField: formState.value.seriesField.value,
			color: props.config.style.chartColor,
			label: props.config.style.showLabel
				? {
						position: props.config.style.labelPosition,
						style: {
							fill: '#000000',
							opacity: 0.6
						},
						layout: [{ type: 'interval-adjust-position' }, { type: 'interval-hide-overlap' }, { type: 'adjust-color' }]
					}
				: false,
			legend: props.config.style.showLegend
				? {
						position: props.config.style.legendPosition
					}
				: false,
			xAxis: {
				label: {
					autoHide: true,
					autoRotate: false
				}
			},
			interactions: [{ type: 'element-active' }]
		}

		// 根据图表类型添加特定配置
		switch (props.config.style.chartType) {
			case 'group':
				return merge({}, baseOptions, {
					isGroup: true,
					// 分组柱状图特有配置
					dodgePadding: 2,
					intervalPadding: 20
				})
			case 'stack':
				return merge({}, baseOptions, {
					isStack: true
				})
			case 'percent':
				return merge({}, baseOptions, {
					isStack: true,
					isPercent: true,
					label: props.config.style.showLabel
						? {
								position: 'middle',
								content: (item) => {
									return `${(item[formState.value.yField.value] * 100).toFixed(2)}%`
								},
								style: {
									fill: '#fff'
								}
							}
						: false
				})
			default: // basic
				return baseOptions
		}
	})

	// 初始化图表
	const initChart = async () => {
		await nextTick()
		if (chartContainer.value && !chartInstance.value) {
			chartInstance.value = new Column(chartContainer.value, chartOptions.value)
			chartInstance.value.render()
		}
	}

	// 处理窗口大小变化
	const handleResize = () => {
		if (!chartInstance.value) return

		try {
			// 尝试使用resize方法
			if (typeof chartInstance.value.resize === 'function') {
				chartInstance.value.resize()
			}
			// 尝试使用内部chart对象的resize方法
			else if (chartInstance.value.chart && typeof chartInstance.value.chart.resize === 'function') {
				chartInstance.value.chart.resize()
			}
			// 如果都不存在，尝试重新渲染
			else {
				chartInstance.value.render()
			}
		} catch (error) {
			console.error('图表重新渲染失败:', error)
		}
	}

	// 监听配置变化，更新图表
	watch(
		() => chartOptions.value,
		(newOptions) => {
			if (chartInstance.value) {
				chartInstance.value.update(newOptions)
			}
		},
		{ deep: true }
	)

	onMounted(async () => {
		await initChart()
		// 使用ResizeObserver监听容器尺寸变化
		if (chartContainer.value) {
			resizeObserver.value = new ResizeObserver(() => {
				handleResize()
			})
			resizeObserver.value.observe(chartContainer.value)
		}
	})

	onBeforeUnmount(() => {
		if (chartInstance.value) {
			chartInstance.value.destroy()
		}
		// 清理ResizeObserver
		if (resizeObserver.value) {
			resizeObserver.value.disconnect()
		}
	})

	// 样式计算
	const container = computed(() => ({
		backgroundColor: props.config.style.bgColor,
		backgroundImage: props.config.style.bgImg ? `url(${props.config.style.bgImg})` : 'none',
		borderStyle: props.config.style.borderStyle,
		borderColor: props.config.style.borderColor,
		borderWidth: props.config.style.borderWidth + 'px',
		paddingTop: props.config.style.paddingT + 'px',
		paddingRight: props.config.style.paddingR + 'px',
		paddingBottom: props.config.style.paddingB + 'px',
		paddingLeft: props.config.style.paddingL + 'px',
		borderTopLeftRadius: props.config.style.bgRTL + 'px',
		borderTopRightRadius: props.config.style.bgRTR + 'px',
		borderBottomLeftRadius: props.config.style.bgRBL + 'px',
		borderBottomRightRadius: props.config.style.bgRBR + 'px',
		boxShadow: `${props.config.style.shadowX}px ${props.config.style.shadowY}px ${props.config.style.shadowDegree}px ${props.config.style.shadowColor}`
	}))

	const titleStyle = computed(() => ({
		fontSize: props.config.style.titleSize + 'px',
		color: props.config.style.titleColor,
		fontWeight: props.config.style.titleWeight ? 'bold' : 'normal',
		fontStyle: props.config.style.titleStyle ? 'italic' : 'normal',
		textDecoration: props.config.style.titleLine ? 'underline' : 'none'
	}))

	const titleIconStyle = computed(() => ({
		fontSize: props.config.style.titleIconSize + 'px',
		color: props.config.style.titleIconColor,
		marginRight: '5px'
	}))

	const titleEndStyle = computed(() => ({
		fontSize: props.config.style.titleEndSize + 'px',
		color: props.config.style.titleEndColor,
		fontWeight: props.config.style.titleEndWeight ? 'bold' : 'normal',
		fontStyle: props.config.style.titleEndStyle ? 'italic' : 'normal',
		textDecoration: props.config.style.titleEndLine ? 'underline' : 'none'
	}))

	const titleEndIconStyle = computed(() => ({
		fontSize: props.config.style.titleEndIconSize + 'px',
		color: props.config.style.titleEndIconColor,
		marginLeft: '5px'
	}))
</script>

<style scoped lang="less">
	.container {
		height: 100%;
		width: 100%;
		display: flex;
		flex-direction: column;
	}

	.title-container {
		display: flex;
		align-items: center;
		margin-bottom: 10px;
	}

	.chart-container {
		flex: 1;
		width: 100%;
		min-height: 100px;
	}
</style>
